package com.woniuxy.goods.manaer.controller;

import com.netflix.discovery.converters.Auto;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.hystrix.contrib.javanica.conf.HystrixPropertiesManager;
import com.woniuxy.goods.manaer.feigns.UserFeignClient;
import com.woniuxy.goods.module.result.Result;
import com.woniuxy.goods.module.result.enums.impl.BusinessCode;
import com.woniuxy.goods.module.result.enums.impl.ResultCode;
import com.woniuxy.goods.module.user.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import javax.ws.rs.Path;
import java.util.List;
import java.util.Map;

@RestController
@Slf4j
// 如果标注了 @HystrixCommand 注解的方法 出现了故障 降级执行 fallbackMethod 方法
//@DefaultProperties(defaultFallback = "fallbackMethod")
public class UserController {

   /* @Autowired
    RestTemplate restTemplate ;
    @Autowired
    DiscoveryClient discoveryClient ;*/
    @Autowired
    UserFeignClient userFeignClient ;

    @PostMapping("/user/login")
//    @HystrixCommand(fallbackMethod = "loginFallbackmethod",commandProperties = {
//
//    })   //降级注解
    public Result<User> login(@RequestBody User user) {
        log.info("接收到的用户名和密码是{},{}",user.getUsername(),user.getPassword());
        //User user1 = restTemplate.postForObject("http://goods-login-server/user/login", user, User.class);
        try {
            User user1 = userFeignClient.loginApi(user);
            //如何知道 进行了降级
            if (user1 != null){
                if (user1.getId() == -1) {
                    //走了降级方法 .......
                    return Result.fail("login登录方法走了降级方法",user1);
                }
                return Result.ok(user1);
            }else {
                return Result.fail(BusinessCode.USER_LOGIN_ERROR.getCode(),BusinessCode.USER_LOGIN_ERROR.getMessage());
            }
        }catch (RuntimeException e) {
            e.printStackTrace();
            return Result.fail(ResultCode.SYSTEM_INNER_ERROR.getCode(),ResultCode.SYSTEM_INNER_ERROR.getMessage());
        }
    }

  /*  public Result<User> loginFallbackmethod(@RequestBody User user){
        log.info("login方法的降级方法:{}",user);
        return Result.fail("login方法的降级方法",user);
    }*/

    /*public Result<User> fallbackMethod(){
        //log.info("降级方法中接收的用户信息:{}",user);
        return Result.fail("服务不可用,目前执行的是降级方法....");
    }*/

    @GetMapping("/user/findUserByKey/{id}")
    @HystrixCommand(fallbackMethod = "errorFallback",commandProperties = {
            // 是否开启断路器
            @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ENABLED,value = "true"),
            // 请求错误率大于 50% 就启动熔断器
            @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE,value = "50"),
            // 默认10秒内访问接口失败达到20次，打开断路器，触发熔断； 为了方便测试，这里修改10秒内错误达到10次触发熔断。  10S内至少发10次请求  错误绿达到50% 就熔断
            @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD,value = "10"),
            //断路多久以后开始尝试是否恢复，默认5s
            @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS,value = "10000")
    })
    public Result<User> findUserByKey(@PathVariable("id") int id) {

        if (id < 10) {
            throw new RuntimeException();
        }

        log.info("接收到的用户id是{}",id);
        User user1 = userFeignClient.findUserByKey(id);
        return Result.ok(user1);
    }
    //熔断中的降级方法
    public Result<User> errorFallback(@PathVariable("id") int id){
        log.info("接收到的用户id是{}",id);

        return Result.fail("findUserByKey 熔断的降级方法.....");
    }
}
